﻿using System;
using System.IO;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
using NUnit.Framework;
using SevenDigital.EndUserManagement.Core.Mapping;

namespace SevenDigital.EndUserManagement.Tests
{
	public class BaseFixture
	{
		private ISessionFactory sessionFactory;
		private const bool OutputDdl = false;
		protected Configuration cfg;

		[TestFixtureSetUp]
		public void TestFixtureSetup() {
			try {
				ConfigureNHibernateConfiguration();
				dbSchemaCreate();
				sessionFactory = cfg.BuildSessionFactory();
				mainSetup();
			} catch (Exception e) {
				Console.WriteLine("Error while setting up test fixture.:{0}", e);
				throw;
			}
		}

		[TestFixtureTearDown]
		public void TestFixtureTearDown() {
			using (ISession session = GetSession()) {
				session.Flush();
				session.Clear();
			}
			dbSchemaDrop();
			cleanup();
		}

		[SetUp]
		public void FixtureSetup() {
			before_each_test();
		}

		[TearDown]
		public void FixtureTearDown() {
			after_each_test();
		}

		protected virtual void after_each_test() {}

		protected virtual void before_each_test() {}

		protected virtual void mainSetup() {}

		private void dbSchemaCreate() {
			new SchemaExport(cfg)
				.SetOutputFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
				                            "buildScript.sql"))
				.Create(OutputDdl, true);
		}

		private void dbSchemaDrop() {
			new SchemaExport(cfg).Drop(OutputDdl, false);
		}

		private void cleanup() {
			sessionFactory.Close();
			sessionFactory = null;
			cfg = null;
		}

		/// <summary>
		/// Any NHibernate.cfg.Configuration goes here.
		/// </summary>
		protected void ConfigureNHibernateConfiguration() {
			cfg = new NHibernateConfiguration()
					.BuildFluentConfigurationForLocalDB()
					.BuildConfiguration();
		}

		protected internal ISessionFactory GetSessionFactory() {
			return sessionFactory;
		}
		protected internal ISession GetSession() {
			return sessionFactory.OpenSession();
		}
	}
}